package com.ssy.lingxi.pay.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ssy.lingxi.common.utils.DateUtil;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * @Auther: Administrator
 * @Date: 2020/1/16 10:46
 * @Description: 通联支付工具类
 */

@Slf4j
public class AllInPayUtils {

    public static PrivateKey privateKey;
    public static PublicKey publicKey;
    public static PublicKey tlPublicKey;



    // 当前类名
    private static String currentClassName = Thread.currentThread().getStackTrace()[1].getClassName();

    // 分配的系统编号
    public static String sysid = "1902271423530473681";

    // public static String publicKey ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEv2q2/xN5PF0dLn1vhIaVlyWsvJFVFxWgH7sQBObzYbZXOOVzoQpmXuSFOrF0/ol4Okd/2OGfdXUUFSUZfzAQOT1Wmjupec7z2V6l4/PT7aOg6t/MJwU9aW9Iw+AFzM1vnLOXdTlWVLZbtB7IiJ/HhfwBDkyvhp1zNYoAPrwC5QIDAQAB";
    // public static String privateKey = "MIID3jCCAsagAwIBAgILAZbujreifSA4bgAwDQYJKoZIhvcNAQEFBQAwdzEcMBoGA1UEAwwTMTkwMjI3MTQyMzUzMDQ3MzY4MTERMA8GA1UECwwIdG9uZ2xpYW4xETAPBgNVBAoMCGFsbGlucGF5MREwDwYDVQQHDAhzaGFuZ2hhaTERMA8GA1UECAwIc2hhbmdoYWkxCzAJBgNVBAYTAkNOMB4XDTE5MDIyNzA2MzA0MloXDTI5MDIyNDA2MzA0MlowdzEcMBoGA1UEAwwTMTkwMjI3MTQyMzUzMDQ3MzY4MTERMA8GA1UECwwIdG9uZ2xpYW4xETAPBgNVBAoMCGFsbGlucGF5MREwDwYDVQQHDAhzaGFuZ2hhaTERMA8GA1UECAwIc2hhbmdoYWkxCzAJBgNVBAYTAkNOMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ/J5gn8lSCxTYkFo2P3CZy+R+KmtYRRc9XP1mFpKUDxcJjmz33g/w1o60WoEeBGnPCDRXMm7xE5wf8qHt24A3XDPqJDARz8UGZytKrZpOZmNAeEP+EAAPhMQHlLIEO2FUGBUrxIdnCLXeTX7N602DbFN5Bh/wmPkgl5JNvSuBOwIDAQABo4HuMIHrMIGoBgNVHSMEgaAwgZ2AFKTlkeCqEh6itzV4CuR6jsUBGQUHoXukeTB3MRwwGgYDVQQDDBMxOTAyMjcxNDIzNTMwNDczNjgxMREwDwYDVQQLDAh0b25nbGlhbjERMA8GA1UECgwIYWxsaW5wYXkxETAPBgNVBAcMCHNoYW5naGFpMREwDwYDVQQIDAhzaGFuZ2hhaTELMAkGA1UEBhMCQ06CCAis0XT/////MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKteRNXpJ0AdTHwEHwKKrYvxWeQYMA4GA1UdDwEB/wQEAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEADXzbSu/fDHtMil7JHwdqPPqvIbkEXwmaA9jgwNz/cedxWSWsjWTC0h6LJnF1mtucNNQcVQ3PLDdlCoW3zE5Sk2uk3m+l8BXXC9ND8uIfVUMumxrZts+JxgmLfK5jf3tOKZvx4UDCNfxGnpWzQe99a8nqVl31FJ1V7tuiX5fYg8vJ/THkNrar28cEPJYeoC3nbFgS5UCsr1IO6F7UnU2wDjUsYvwXxlRIRDWUP5ulGfSnjQQfsYvcYkdLpsdEH6GvNaBGiEVpqDwV4bJzv9mhgAjEjBqUC8BtwIHoKeroApJHuUaqOQCnPfjO+GjVj2kv/ydgG57Gwc4c5sBbdzqOKQ==";
    private static Provider provider = new BouncyCastleProvider();

    // 测试环境接口地址：http://116.228.64.55:6900/service/soa
    public final static String testInterfaceURL = "http://116.228.64.55:6900/service/soa";
    // 测试环境网关地址：http://116.228.64.55:6900/yungateway/frontTrans.do
    public static String testGatewayURL = "http://116.228.64.55:6900/yungateway/frontTrans.do";
    // 测试环境门户地址：http://116.228.64.55:6901/portal
    public static String testPortalURL = "http://116.228.64.55:6901/portal";
    // 生产环境接口地址：https://fintech.allinpay.com/service/soa
    public static String procInterfaceURL = "https://fintech.allinpay.com/service/soa";
    // 生产环境网关地址：https://fintech.allinpay.com /yungateway/frontTrans.do
    public static String procGatewayURL = "http://fintech.allinpay.com/yungateway/frontTrans.do";
    // 生产环境门户地址：https://fintech.allinpay.com/portal
    public static String procPortalURL = "https://fintech.allinpay.com/portal";



    /**
     * 发送请求
     * @param paramsMap
     * @return
     * @throws Exception
     */
    public static String request(Map<String, String> paramsMap) throws Exception {
        String resp = post(paramsMap);
        if (StringUtil.isEmpty(resp)) {
            throw new Exception("no response data returned");
        } else {
            return verify(resp);
        }
    }

    /**
     *验签
     * @param resp
     * @return
     * @throws Exception
     */
    public static String verify(String resp) throws Exception {
        Map<String, String> respMap = (Map) JSON.parseObject(resp, Map.class);
        String value = (String)respMap.get("signedValue");
        if (StringUtil.isEmpty(value)) {
            throw new Exception("return error,signedValue is null");
        }
        String sign = (String)respMap.get("sign");
        if (StringUtil.isEmpty(sign)) {
            throw new Exception("return ,sign is null");
        }
        if (!AllInPayUtils.verify(value, sign)) {
            throw new Exception("verify sign error");
        } else {
            if ("OK".equals(respMap.get("status"))) {
                Object obj = JSON.parse(value);
                if (obj instanceof Map) {
                    Map<String, Object> ret = (Map)obj;
                    if (ret.get("$PrimitiveReturn$") != null) {
                        respMap.put("returnValue", JSON.toJSONString(ret.get("$PrimitiveReturn$")));
                    }
                } else {
                    respMap.put("returnValue", value);
                }
            }

            return JSON.toJSONString(respMap);
        }
    }

    /**
     * 获取商户私钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return
     * @throws Exception
     */
    public static PrivateKey loadPrivateKey(String alias, String path, String password) throws Exception {
        FileInputStream ksfis = null;
        alias = "1902271423530473681";
        File file = ResourceUtils.getFile("classpath:allInPay/1902271423530473681.pfx");
        path = file.getPath();
        password = "123456";
        PrivateKey var7;
        try {
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ksfis = new FileInputStream(path);
            char[] storePwd = password.toCharArray();
            char[] keyPwd = password.toCharArray();
            ks.load(ksfis, storePwd);
            var7 = (PrivateKey) ks.getKey(alias, keyPwd);
            privateKey = var7;
        } finally {
            if (ksfis != null) {
                ksfis.close();
            }

        }

        return var7;
    }

    /**
     * 获取商户公钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return
     * @throws Exception
     */
    public static PublicKey loadPublicKey(String alias, String path, String password) throws Exception {
        FileInputStream ksfis = null;
        alias = "1902271423530473681";
        // path = "E:\\Work\\1902271423530473681.pfx";
        File file = ResourceUtils.getFile("classpath:allInPay/1902271423530473681.pfx");
        path = file.getPath();
        password = "123456";
        PublicKey var6;
        try {
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ksfis = new FileInputStream(path);
            char[] storePwd = password.toCharArray();
            ks.load(ksfis, storePwd);
            var6 = ks.getCertificate(alias).getPublicKey();
            publicKey = var6;
        } finally {
            if (ksfis != null) {
                ksfis.close();
            }

        }

        return var6;
    }

    /**
     * 获取通联公钥
     *
     * @param certPath 公钥所在路径
     * @return 返回公钥信息
     * @throws Exception
     */
    public static PublicKey loadTLPublicKey(String certPath) {
        FileInputStream certInputStream = null;
        PublicKey pubKey = null;
        try {
            File file = ResourceUtils.getFile("classpath:allInPay/TLCert-test.cer");
            String path = file.getPath();
            // certPath = "E:\\Work\\TLCert-test.cer";


            CertificateFactory certificatefactory = null;
            certificatefactory = CertificateFactory.getInstance("X.509");

            certInputStream = new FileInputStream(path);
            X509Certificate Cert = (X509Certificate) certificatefactory.generateCertificate(certInputStream);
            pubKey = Cert.getPublicKey();
            tlPublicKey = pubKey;
        } catch (IOException var8) {
            var8.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } finally {
            if (certInputStream != null) {
                try {
                    certInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return pubKey;
    }

    /**
     * 签名
     * 步骤 1：先对签名源串用 MD5 算法进行摘要计算；
     * 步骤 2：对步骤 1 的返回数据进行 Base64 编码；
     * 步骤 3：对步骤 2 的返回数据使用商户私钥进行 SHA1WithRSA 算法签名；
     * 步骤 4：对步骤 3 的返回数据进行 Base64 编码。
     *
     * @param text 签名源串：sysid（系统编号） + req（服务请求的JSON对象） + timestamp（请求时间戳）
     * @return
     * @throws Exception
     */
    public static String sign(String text) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        String encode = null;
        try {
            Signature signature = Signature.getInstance("SHA1WithRSA", provider);
            //Signature signature = Signature.getInstance("SHA1WithRSA");
            // 步骤1和2
            text = md5(text);
            signature.initSign(loadPrivateKey(null, null, null));
            // 步骤 3：对步骤2的返回数据使用商户私钥进行SHA1WithRSA算法签名； ==> Signature.getInstance("SHA1WithRSA")
            signature.update(text.getBytes(Charset.forName("UTF-8")));
            byte[] data = signature.sign();
            // 步骤 4：对步骤 3 的返回数据进行 Base64 编码。
            encode = Base64.encode(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encode;
    }

    /**
     * MD5验签
     *
     * @param src
     * @return
     */
    public static String md5(String src) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        String result = "";
        try {
            // 步骤 1：先对签名源串用 MD5 算法进行摘要计算；
            MessageDigest md = MessageDigest.getInstance("MD5");
//            result = Base64.encode(md.digest(src.getBytes("utf-8")));
            // 步骤 2：对步骤 1 的返回数据进行 Base64 编码；
            result = Base64.encode(md.digest(src.getBytes("utf-8")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 验签
     * 步骤 1：先对签名源串用 MD5 算法进行摘要计算；
     * 步骤 2：对步骤 1 的返回数据进行 Base64 编码；
     * 步骤 3：对响应报文中的签名串 sign 进行 Base64 解码；
     * 步骤 4：对步骤 2、3 的返回数据使用通联公钥进行 SHA1WithRSA 算法验签。
     * 验签结果为 true 则说明验证签名成功，否则验证签名失败。
     * 注：验签前需要 urldecode 解码，部分语言在获取参数时会自动解码，请注意。
     *
     * @param publicKey
     * @param text
     * @param sign
     * @return
     * @throws Exception
     */
    public static boolean verify(PublicKey publicKey, String text, String sign) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        boolean flag = false;
        try {
            Signature signature = Signature.getInstance("SHA1WithRSA", provider);
            //           Signature signature = Signature.getInstance("SHA1WithRSA");
            signature.initVerify(publicKey);
            // 步骤1和2
            text = md5(text);
            signature.update(text.getBytes("UTF-8"));
            // 步骤 3：对响应报文中的签名串 sign 进行 Base64 解码；
            byte[] signed = Base64.decode(sign);
            // 步骤 4：对步骤 2、3 的返回数据使用通联公钥进行 SHA1WithRSA 算法验签。==> Signature.getInstance("SHA1WithRSA")
            flag = signature.verify(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("验证状态：{}", flag);
        return flag;
    }

    /**
     * JSON转字符串
     *
     * @param object
     * @return
     */
    public static String jsonToStr(Object object) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        return JSON.toJSONString(object);
    }

    /**
     * 字符串转json
     *
     * @param str
     * @return
     */
    public static Map<String, Object> strToJson(String str) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        return JSON.parseObject(str, new TypeReference<TreeMap<String, Object>>() {
        });
//        return JSON.parseObject(str, TreeMap.class);
    }

    /**
     * 获取公钥对象
     *
     * @return
     */
    public static PublicKey getPublicKey() {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        PublicKey publicKeyObj = null;
        X509EncodedKeySpec keySpec = null;
        try {
            keySpec = new X509EncodedKeySpec(Base64.decode("publicKey"));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKeyObj = keyFactory.generatePublic(keySpec);
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return publicKeyObj;
    }

    /**
     * 获取私钥对象
     *
     * @return
     */
    public static PrivateKey getPrivateKey() {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        PrivateKey privateKeyObj = null;
        PKCS8EncodedKeySpec priPKCS8 = null;
        try {
            priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode("null"));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            privateKeyObj = keyf.generatePrivate(priPKCS8);
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return privateKeyObj;
    }

    /**
     * String 转换为publickey
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static PublicKey gettoPublicKey(String key) throws Exception {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        byte[] keyBytes = Base64.decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * String转私钥PrivateKey
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static PrivateKey gettoPrivateKey(String key) throws Exception {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        byte[] keyBytes;
        keyBytes = Base64.decode(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    // ==========================接口定义三连杀==============================
    //最终请求报文reqMsgToStr--> 初步请求报文reqMsg --> 服务请求的JSON req --> 请求参数param

    /**
     * 最终请求报文格式
     *
     * @param req
     * @return
     */
    public static Map<String, String> reqMsgToStr(Map<String, Object> req) {
        Map<String, String> paramsMap = new HashMap<>();
        for (String key : req.keySet()) {
            paramsMap.put(key, String.valueOf(req.get(key)));
        }
        return paramsMap;
    }

    /**
     * 初始化请求报文
     *
     * @return
     */
    public static Map<String, Object> reqMsg(Map<String, Object> req) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        Map<String, Object> result = new HashMap<>();

        String timestamp = DateUtil.timeStamp2Date(System.currentTimeMillis(), null);
        // 分配的系统编号
        result.put("sysid", sysid);

        // text签名源串：sysid（系统编号） + req（服务请求的JSON对象） + timestamp（请求时间戳）
//        String text = AllInPayUtils.sysid + req + timestamp;
        // req应该要从Map转为JSON字符串
        String text = sysid + jsonToStr(req) + timestamp;
        log.info("text签名源串：{}", text);
        // 签名
        String sign = sign(text);
        log.info("签名sign：{}", sign);
        result.put("sign", sign);

        // 验签
        boolean verify = verify(loadTLPublicKey(null), text, sign);
      /*  if (!verify) {
            throw new RuntimeException("验签失败");
        }*/
        // 请求时间戳  格式：yyyy-MM-ddHH:mm:ss
        result.put("timestamp", timestamp);
        // 接口版本(现为 2.0)
        result.put("v", "2.0");
        // 服务请求的 JSON 对象
        result.put("req", AllInPayUtils.jsonToStr(req));
        Map<String, Object> reqmap = AllInPayUtils.strToJson(String.valueOf(result.get("req")));
        log.info("sysid：{}，sign：{}，timestamp：{}，v：{}，req：{}，param：{}",
                result.get("sysid"), result.get("sign"), result.get("timestamp"),
                result.get("v"), result.get("req"), reqmap.get("param"));
        log.info("result：{}", result);
        return result;
    }

    /**
     * 构建服务请求的 JSON req对象，参与签名
     *
     * @param service 服务对象
     * @param method  调用方法
     * @param param   请求参数
     * @return
     */
    public static Map<String, Object> req(String service, String method, Map<String, Object> param) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        // 服务请求的 JSON 对象，参与签名
        Map<String, Object> req = new HashMap<>();
        // 服务对象
        req.put("service", service);
        // 调用方法
        req.put("method", method);
        // 请求参数
        req.put("param", param);
        log.info("service：{}，method：{}，param：{}", service, method, param);
        log.info("req：{}", req);
        return req;
    }

    /**
     * 请求参数，嵌套的 JSON 对象
     *
     * @param bizUserId 商户系统用户标识，商户系统中唯一编号。注意：1.不能输入“中文” 2.不要使用系统保留用户标识：#yunBizUserId_B2C#
     * @return
     */
    public static Map<String, Object> param(String bizUserId) {
        log.info("当前类名：{}", currentClassName);
        log.info("当前方法名称：{}", Thread.currentThread().getStackTrace()[1].getMethodName());
        // 请求参数，嵌套的 JSON 对象
        Map<String, Object> param = new HashMap<>();
        // 商户系统用户标识，商户系统中唯一编号
        param.put("bizUserId", bizUserId);
        log.info("param：{}", param);
        return param;
    }

    /**
     * 处理请求数据 拼接成k1=v1&k2=v2。。。。同时编码处理
     *
     * @param paramsMap
     * @return
     * @throws Exception
     */

    public static String encodeOnce(Map<String, String> paramsMap) throws Exception {
        StringBuilder sb = new StringBuilder();
        System.out.println("encodeOnce：" + paramsMap);
        String key;
        String value;
        for (Iterator var3 = paramsMap.entrySet().iterator(); var3.hasNext(); sb.append(key).append("=").append(URLEncoder.encode(value, "utf-8")).append("&")) {
            Map.Entry<String, String> entry = (Map.Entry) var3.next();
            key = (String) entry.getKey();
            value = (String) entry.getValue();
            System.out.println(key + ":" + value);
            if (value == null) {
                value = "";
            }
        }

        return sb.toString();
    }

    /**
     * 发送post的form表单请求
     *
     * @param paramsMap
     * @return
     * @throws Exception
     */
    private static String post(Map<String, String> paramsMap) throws Exception {
        String param = encodeOnce(paramsMap);
        // String param = AllInPayUtils.jsonToStr(paramsMap);
        System.out.println("请求参数：" + param);
        StringBuilder result = new StringBuilder();
        BufferedWriter writer = null;
        BufferedReader reader = null;

        try {
            URL httpUrl = new URL(AllInPayUtils.testInterfaceURL);
            HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
            connection.setRequestProperty("Connection", "keep-alive");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "utf-8"));
            writer.write(param);
            writer.flush();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
        } catch (IOException var16) {
            var16.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }

                if (reader != null) {
                    reader.close();
                }
            } catch (IOException var15) {
                var15.printStackTrace();
            }

        }

        return result.toString();
    }

    /**
     * 验签
     *
     * @param text 通联支付返回的值
     * @param sign 签名
     * @return 验签结果
     * @throws Exception
     */
    public static boolean verify(String text, String sign) throws Exception {
        return verify1(tlPublicKey, text, sign);
    }

    /**
     * @param publicKey 通联公钥
     * @param text      通联支付返回的值
     * @param sign      签名
     * @return 验签结果
     * @throws Exception
     */
    public static boolean verify1(PublicKey publicKey, String text, String sign) throws Exception {
        Signature signature = Signature.getInstance("SHA1WithRSA", provider);
        signature.initVerify(publicKey);
        text = md5(text);
        signature.update(text.getBytes("UTF-8"));
        byte[] signed = Base64.decode(sign);
        return signature.verify(signed);
    }

    /**
     * 静态代码块：读取商户公私钥和通联公钥
     */
   /* static {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream("E:\\Work\\TLCert-test.cer"));
            PublicKey key = cert.getPublicKey();
            BASE64Encoder base64Encoder = new BASE64Encoder();
            String publicKeyString = base64Encoder.encode(key.getEncoded());
            System.out.println("-----------------公钥--------------------");
            System.out.println(publicKeyString);
            tlPublicKey = key;
            System.out.println("-----------------公钥--------------------");
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


        String strPfx = "E:\\Work\\1902271423530473681.pfx";
        String strPassword = "123456";
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(strPfx);
            // If the keystore password is empty(""), then we have to set
            // to null, otherwise it won't work!!!
            char[] nPassword = null;
            if ((strPassword == null) || strPassword.trim().equals("")) {
               nPassword = null;
            } else {
                nPassword = strPassword.toCharArray();
            }
            ks.load(fis, nPassword);
            fis.close();
            System.out.println("keystore type=" + ks.getType());
            // Now we loop all the aliases, we need the alias to get keys.
            // It seems that this value is the "Friendly name" field in the
            // detals tab <-- Certificate window <-- view <-- Certificate
            // Button <-- Content tab <-- Internet Options <-- Tools menu
            // In MS IE 6.
            Enumeration enumas = ks.aliases();
            String keyAlias = null;
            if (enumas.hasMoreElements())// we are readin just one certificate.
            {
                keyAlias = (String) enumas.nextElement();
                System.out.println("alias=[" + keyAlias + "]");
            }
            // Now once we know the alias, we could get the keys.
            System.out.println("is key entry=" + ks.isKeyEntry(keyAlias));
            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
            //  privateKey = prikey;
            Certificate cert = ks.getCertificate(keyAlias);
            PublicKey pubkey = cert.getPublicKey();
            //  publicKey=pubkey;
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        }
    }
    */

}
